package launcher;

import illustration.PrReGraph;
import illustration.PrReEntry;
import illustration.ROCEntry;
import illustration.ROCGraph;

import java.io.File;
import java.util.Vector;

import org.jfree.ui.RefineryUtilities;

import classifier.LabeledData;
import classifier.NaiveBayesClassifier;
import data.Corpus;

public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Corpus corp = new Corpus(CORPUS_PATH);
		NaiveBayesClassifier classifier = new NaiveBayesClassifier(corp
				.getVocabulary());

		Vector<Integer> estimatedLabels = new Vector<Integer>();
		
		Vector<Vector<ROCEntry>> entries = new Vector<Vector<ROCEntry>>();
		Vector<ROCEntry> meanEntries = new Vector<ROCEntry>();

                Vector<Vector<PrReEntry>> PrReEntries = new Vector<Vector<PrReEntry>>();
                Vector<PrReEntry> meanPrRe = new Vector<PrReEntry>();

		ROCGraph ROC_graph;
                PrReGraph PR_graph;

		// Significance Levels
		Vector<Double> levels = new Vector<Double>();
		
		// For a nice plot use: 
		//for (double i = -0.2; i <= 0.2; i += 0.01) {
		
		// For a fast plot use:
		for (double i = -0.1; i <= 0.1; i += 0.025) {
			levels.add(i);
		}

		// N-fold
		int N = 10;
		
		for (int fold = 0; fold < N; fold++) 
		{
			
			Vector<ROCEntry> entriesForFold = new Vector<ROCEntry>();
                        Vector<PrReEntry> Single_PrReEntry = new Vector<PrReEntry>();
			
			classifier.train(corp.getTrainingData(fold));
			// Validation
			Vector<LabeledData<Vector<String>>> testDataWithLabels = corp.getTestDataWithLabels(fold);
			
			for (Double level : levels) 
			{
				estimatedLabels = classifier.classify(corp.getTestData(fold),level);
				
				double count = 0;
				double count_matches = 0;
				double countRealSpam = 0;
				double countRealNoSpam = 0;
				double falsePositives = 0;
				double truePositives = 0;
				for (int i = 0; i < testDataWithLabels.size(); i++)
				{
					if (estimatedLabels.get(i) == testDataWithLabels.get(i).getLabel()) {
						count_matches++;

					}
					if (testDataWithLabels.get(i).getLabel() == 1) {
						countRealSpam++;
						if (estimatedLabels.get(i) == 1) {
							truePositives++;
						}
					} else {
						if(estimatedLabels.get(i) == 1)
						{
							falsePositives++;
						}
						countRealNoSpam++;
					}

					count++;
				}
//				System.out.println("Correctly classified rate (fold" + fold
//				+ "): " + count_matches / count + " (" + count_matches
//				+ "/" + count + ")");
				entriesForFold.add(new ROCEntry(falsePositives / countRealNoSpam, truePositives / countRealSpam));
                                Single_PrReEntry.add(new PrReEntry((truePositives + 0.001) / (truePositives + falsePositives + 0.001), truePositives / countRealSpam));
			}
			
			entries.add(entriesForFold);
                        PrReEntries.add(Single_PrReEntry);
		}
		
		int size = entries.size();
		for(int i=0;i<entries.get(0).size();i++)
		{
			double tp = 0;
			double fp = 0;
                        double precision = 0;
                        double recall = 0;

			for(int j=0; j<size; j++)
			{
				ROCEntry e = entries.get(j).get(i);
				fp += e.getFalsePositiveRate();
				tp += e.getTruePositiveRate();

                                precision += PrReEntries.get(j).get(i).getPrecision();
                                recall += PrReEntries.get(j).get(i).getRecall();

			}
			meanEntries.add(new ROCEntry(fp/size,tp/size));
                        meanPrRe.add(new PrReEntry(precision/size, recall/size));

		}
		
		ROC_graph = new ROCGraph(meanEntries);
		ROC_graph.pack();
		RefineryUtilities.centerFrameOnScreen(ROC_graph);
		ROC_graph.setVisible(true);
                
                PR_graph = new PrReGraph(meanPrRe);
		PR_graph.pack();
		RefineryUtilities.centerFrameOnScreen(PR_graph);
		PR_graph.setVisible(true);
                
                
                
                /*
                for(int i=0;i<meanPrRe.size();i++) {
                    System.out.println("Precision: " + meanPrRe.get(i).getPrecision() + "| Recall: " + meanPrRe.get(i).getRecall());
                }
                */
                
                
	}
	
	
	private static final String CORPUS_PATH = "data" + File.separator + "spam_corpus";

}
